home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !preview / c / build next >
Encoding:
Text File  |  1990-07-26  |  18.6 KB  |  792 lines

  1. /* build.c --- Build the data structure as presented from the dvi file by
  2.    dviread.  */
  3.  
  4. #include "d2rd.h"
  5. #include "bbc.h"
  6. #include "font.h"
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <stdarg.h>
  11. #include "kernel.h"
  12. #include "visdelay.h"
  13. #include "template.h"
  14. #include "colourtran.h"
  15. #include "res.h"
  16. #include "flex.h"
  17.  
  18. /* The allocation units while reading a dvi file.  Maybe these could just be
  19.    very large numbers, since the appriopriate arrays are re-alloc'd to the
  20.    right size afterwards anyway, or maybe not...  */
  21.  
  22. #define RULE_BLOCKSIZE     10
  23. #define TEXT_BLOCKSIZE     100
  24. #define CHAR_BLOCKSIZE     200
  25.  
  26.  
  27. /* Set this variable to 1 to be blown away by gunge while loading a dvi file.  */
  28.  
  29. extern int debug;
  30.  
  31.  
  32. /* CURRENT_DVI_FILE points to the struct dvi_file of the file currently being read.  */
  33.  
  34. struct dvi_file *current_dvi_file;
  35.  
  36.  
  37. /* CURRENT_PAGE idem dito of the current page.  PAGE_PTR points to the
  38.    pointer which should point to this page, which it indeed will as soon as
  39.    this page is completely loaded.  */
  40.  
  41. static struct page **page_ptr, *current_page;
  42.  
  43.  
  44. /* Possible \magstep values (magstep0, magstephalf, magstep1, ..., magstep5)
  45.    in the order of the magnification submenu.  */
  46.  
  47. double tex_magstep[] = {1.000, 1.095, 1.200, 1.440, 1.728, 2.074, 2.488};
  48.  
  49.  
  50. /* The fonthandle while reading the dvi file, as set by the last call to
  51.    setfont.  */
  52.  
  53. int current_font_handle;
  54.  
  55.  
  56. static int current_page_number;
  57.  
  58. int draw_page = 1;
  59.  
  60. int page_area_size;
  61.  
  62. int loading_a_file;
  63.  
  64. int x_os_scale, y_os_scale;
  65.  
  66. int rule_index, char_index, text_index;
  67.  
  68. int max_rule_index, max_char_index, max_text_index;
  69.  
  70.  
  71.  
  72. struct
  73. {
  74.   char val[1024];
  75.   _kernel_swi_regs r;
  76. } old_font;
  77.  
  78.  
  79. /* This sets the Font$Path to my own fonts.  It saves the old Font$Prefix
  80.    properly, which can't be done by getenv () and setenv () in case the
  81.    variable is something like a macro.  Hence this _kernel_swi () stuff.  */
  82.  
  83. void
  84. set_font_path (void)
  85. {
  86.   char *new_font_path;
  87.  
  88.   old_font.r.r[0] = (int) "Font$Path";
  89.   old_font.r.r[1] = (int) &old_font.val[0];
  90.   old_font.r.r[2] = 1024;
  91.   old_font.r.r[3] = old_font.r.r[4] = 0;
  92.   _kernel_swi (0x23, &old_font.r, &old_font.r);
  93.  
  94.   new_font_path = getenv ("PreviewFonts$Path");
  95.   if (new_font_path == NULL)
  96.     tfatal ("PreviewFonts$Path is not defined!");
  97.  
  98.   _kernel_setenv ("Font$Path", new_font_path);
  99. }
  100.  
  101.  
  102. void
  103. reset_font_path (void)
  104. {
  105.   old_font.r.r[3] = 0;
  106.   _kernel_swi (0x24, &old_font.r, &old_font.r);
  107. }
  108.  
  109.  
  110. /* Set the default values of a window.  */
  111.  
  112. void
  113. default_display_values (struct display *w)
  114. {
  115.   w->hor_size = (int)(A4_WIDTH  * MILLIPOINTS);
  116.   w->ver_size = (int)(A4_HEIGHT * MILLIPOINTS);
  117.   w->hor_offset = 1 * MILLIPOINTS; /* one inch, in millipoints */
  118.   w->ver_offset = 1 * MILLIPOINTS; /* one inch, in millipoints */
  119.   w->magstep = 0; w->mag_tweak = 1.0;
  120.   w->zoom = 0;
  121. }
  122.  
  123.  
  124. void
  125. factors (struct display *w, double *x, double *y)
  126. {
  127.   *x = *y = tex_magstep[w->magstep] * w->mag_tweak;
  128. }
  129.  
  130.  
  131. void
  132. fill_sprite (struct display *w)
  133. {
  134.   struct dvi_file *f = w->file;
  135.   struct font_use *fu;
  136.   struct page *p = w->page;
  137.   struct text *t;
  138.   struct rule *l;
  139.   wimp_palettestr current_palette;
  140.   wimp_paletteword pal;
  141.   _kernel_swi_regs r;
  142.   int h, i, k, x, y, dvi_to_handle[256];
  143.   int things = 0, bpp = bbc_vduvar (bbc_Log2BPP);
  144.   double xs, ys;
  145.  
  146.   visdelay_begin ();
  147.   set_font_path ();
  148.  
  149.   for (i = 0; i < 256; i++)
  150.     dvi_to_handle[i] = 0;
  151.  
  152.   wimp_readpalette (¤t_palette);
  153.  
  154.   r.r[0] = 60 + 256;
  155.   r.r[1] = (int) w->area;
  156.   r.r[2] = (int) w->sid.s.name;
  157.   r.r[3] = 0;
  158.  
  159.   err = (os_error *) _kernel_swi (0x2e, &r, &r);
  160.   if (err)
  161.     tfatal ("Can't redirect output to sprite: %s\n", err->errmess);
  162.  
  163.   /* Output is now to the sprite.  */
  164.  
  165.   wimp_setpalette (¤t_palette);
  166.  
  167.   pal.word = -1; pal.bytes.gcol = 0;
  168.   colourtran_setGCOL (pal, 128, 0, &i);
  169.   bbc_clg ();
  170.  
  171.   factors (w, &xs, &ys);
  172.  
  173.   pal.word = -1;
  174.  
  175.   for (t = p->texts, i = 0; i < p->text_max; t++, i++)
  176.     {
  177.       /* If the dvi to handle translation results in 0, the font has not been
  178.          found yet.  Thus, find it at the appropriate size.  */
  179.  
  180.       if (t->font > 255)
  181.         tfatal ("fontno = %d\n", t->font);
  182.  
  183.       if (dvi_to_handle[t->font] == 0)
  184.         {
  185.           fu = f->fonts[t->font];
  186.           err = font_find (fu->name, (int) (fu->size * xs), (int) (fu->size * ys), 0, 0, &dvi_to_handle[t->font]);
  187.           if (err)
  188.             {
  189.               dvi_to_handle[t->font] = 0;
  190.               continue;
  191.             }
  192.         }
  193.  
  194.       font_setcolour (dvi_to_handle[t->font], 0, 1, bpp == 0 ? 0 : bpp == 1 ? 2 : bpp == 2 ? 6 : 14);
  195.       font_paint (&p->chars[t->text], 0, (int)(t->x * xs),
  196.          (int)((w->ver_size - w->ver_offset - t->y) * ys));
  197.       visdelay_percent ((100 * things++) / p->things);
  198.     }
  199.  
  200.   for (i = 0; i < 256; i++)
  201.     if (dvi_to_handle[i])
  202.       font_lose (dvi_to_handle[i]);
  203.  
  204.   pal.word = 0;
  205.   colourtran_setGCOL (pal, 0, 0, &i);
  206.  
  207.   for (l = p->rules, i = 0; i < p->rule_max; l++, i++)
  208.     {
  209.       visdelay_percent ((100 * things++) / p->things);
  210.       font_converttoos ((int)(l->x * xs),
  211.          (int)((w->ver_size - w->ver_offset - l->y) * ys), &x, &y);
  212.       font_converttoos ((int) (l->w * xs), (int) (l->h * ys), &k, &h);
  213.       bbc_rectanglefill (x, y, k, h);
  214.     }
  215.  
  216.   /* Re-redirect output to the screen again.  */
  217.  
  218.   _kernel_swi (0x2e, &r, &r);
  219.  
  220.   reset_font_path ();
  221.  
  222.   visdelay_percent (-1);
  223.   visdelay_end ();
  224. } /* fill_sprite */
  225.  
  226.  
  227.  
  228. /********
  229.   */
  230.  
  231. int
  232. define_sprite (struct display *w)
  233. {
  234.   char *sprite_name = xmalloc (12);
  235.   double xfac, yfac;
  236.   int xpix, ypix;
  237.   int size;
  238.  
  239.   factors (w, &xfac, &yfac);
  240.  
  241.   font_converttoos( (int)((w->hor_size - w->hor_offset) * xfac),
  242.                     (int)((w->ver_size - w->ver_offset) * yfac),
  243.                     &xpix, &ypix);
  244.  
  245.   xpix /= x_os_scale; xpix = (xpix+31) & ~31;
  246.   ypix /= y_os_scale;
  247.  
  248.   size = (int) (1024 +
  249.      (xpix * ypix * (1 << bbc_vduvar (bbc_Log2BPP))) / 8.0);
  250.  
  251. #ifdef USE_FLEX
  252.   if (flex_alloc ((flex_ptr) &w->area, size) == 0)
  253.     tfatal ("failed to allocate space for aprite area");
  254. #else
  255.   w->area = xmalloc (size);
  256. #endif
  257.  
  258.   sprite_area_initialise (w->area, size);
  259.  
  260.   sprintf (sprite_name, "page");
  261.   w->sid.tag =0;
  262.   w->sid.s.name = sprite_name;
  263.  
  264.   err = sprite_create (w->area, sprite_name, TRUE,
  265.                        xpix, ypix, vdu_mode);
  266.   if (err)
  267.     tfatal ("Can't create sprite: %s\n", err->errmess);
  268.  
  269.   return (0);
  270. } /* define_sprite */
  271.  
  272.  
  273.  
  274. void
  275. adjust_window_size (struct display *w)
  276. {
  277.   wimp_redrawstr r;
  278.   wimp_wstate s;
  279.   double xfac, yfac;
  280.  
  281.   factors (w, &xfac, &yfac);
  282.  
  283.   r.w = w->w_handle;
  284.   r.box.x0 = 0;
  285.   r.box.y0 = 0;
  286.   font_converttoos((int)(w->hor_size*xfac), (int)(w->ver_size*yfac), &r.box.x1, &r.box.y1);
  287.   wimpt_noerr (wimp_set_extent (&r));
  288.  
  289.   r.w = w->w_handle;
  290.   r.box.x0 = 0;
  291.   r.box.y0 = 0;
  292.   r.box.x1 = 1 << 30;
  293.   r.box.y1 = 1 << 30;
  294.   wimpt_noerr (wimp_force_redraw (&r));
  295.  
  296.   wimp_get_wind_state (w->w_handle, &s);
  297.   wimp_open_wind (&s.o);
  298. } /* adjust_window_size */
  299.  
  300.  
  301.  
  302. void
  303. set_window_title (struct display *w)
  304. {
  305.   wimp_wstate ws;
  306.  
  307.   sprintf (w->w_title, "%s %d%s", w->file->f_name, w->page->dvi_page, w->file->complete ? "" : " *");
  308.   wimpt_noerr (wimp_get_wind_state (w->w_handle, &ws));
  309.   ws.o.box.x1 -= 4;
  310.   wimpt_noerr (wimp_open_wind (&ws.o));
  311.   ws.o.box.x1 += 4;
  312.   wimpt_noerr (wimp_open_wind (&ws.o));
  313. }
  314.  
  315.  
  316.  
  317. void
  318. build_a_window (struct dvi_file *df, struct page *p)
  319. {
  320.   struct display *w;
  321.   wimp_wind *wind;
  322.   wimp_openstr wop;
  323.   double xfac, yfac;
  324.  
  325.   w = xcalloc (1, sizeof (struct display));
  326.   w->file = df;
  327.   w->page = p;
  328.  
  329.   w->w_title = xmalloc (300);
  330.   sprintf (w->w_title, "%s", df->f_name);
  331.  
  332.   default_display_values (w);
  333.   define_sprite (w);  
  334.   fill_sprite (w);
  335.  
  336.   wind = template_syshandle ("yesyes");
  337.   factors (w, &xfac, &yfac);
  338.  
  339.   wind->ex.x0 = 0;
  340.   wind->ex.y0 = 0;
  341.   font_converttoos((int)(w->hor_size*xfac), (int)(w->ver_size*yfac),
  342.       &wind->ex.x1, &wind->ex.y1);
  343.   wind->titleflags |= wimp_ITEXT | wimp_INDIRECT ;
  344.   wind->titleflags &= ~(wimp_ISPRITE);
  345.   wind->title.indirecttext.buffer = w->w_title;
  346.   wind->title.indirecttext.validstring = NULL;
  347.   wind->title.indirecttext.bufflen = 300;
  348.  
  349.   wimpt_noerr (wimp_create_wind (wind, &w->w_handle));
  350.  
  351.   /*
  352.   ** Having created the window, we now open it.
  353.   ** Initially, the part of the work area we want visible
  354.   ** is the middle of the topmost part.  We can skip part
  355.   ** of the top margin, too, as it won't have anything in it.
  356.   */
  357.   wop.w = w->w_handle;
  358.   wop.box = wind->box;
  359.   font_converttoos( 0, (int)((w->ver_size-(w->ver_offset/2)) * yfac),
  360.                     &wop.x, &wop.y );
  361.   wop.x = (wind->ex.x1-(wop.box.x1-wop.box.x0))/2;
  362.   if (wop.x<0) wop.x = 0; /* in case of smaller work area than window */
  363.   wop.behind = -1;
  364.   wimp_open_wind (&wop);
  365.  
  366.   set_window_title (w);
  367.  
  368.   w->next = windows;
  369.   windows = w;
  370. } /* build_a_window */
  371.  
  372.  
  373.  
  374. /**********
  375.    Read a dvifile and build a dvi_file structure.  Return 0 if no error
  376.    occured, +1 if an error occured and the user has already been notified, -1
  377.    otherwise.  */
  378.  
  379. int
  380. read_a_file (char *name)
  381. {
  382.   char *dviread_argv[2], *xname, *real_name;
  383.   struct dvi_file *df;
  384.   struct display *w;
  385.   FILE *f;
  386.  
  387.   if (loading_a_file)
  388.     {
  389.       fatal ("Already loading a file.  Please wait.");
  390.       return (1);
  391.     }
  392.  
  393.   /* If NAME is a directory, try looking for a file called dvi in there.  If
  394.      this exists, correct NAME. */
  395.  
  396.   xname = malloc (5 + strlen (name));
  397.   sprintf (xname, "%s.dvi", name);
  398.   f = fopen (xname, "rb");
  399.   fclose (f);
  400.   real_name = (f == NULL ? name : xname);
  401.  
  402.   /* If this file is already loaded bring his window to the front so the user
  403.      will see this as well (and spot the `mistake').  */
  404.  
  405.   for (w = windows; w; w = w->next)
  406.     if (strcmp (w->file->f_name, real_name) == 0)
  407.       {
  408.         wimp_wstate r;
  409.  
  410.         wimpt_complain (wimp_get_wind_state (w->w_handle, &r));
  411.         r.o.behind = -1;
  412.         wimpt_complain (wimp_open_wind (&r.o));
  413.         free (xname);
  414.         return (0);
  415.       }
  416.  
  417.   /* Alles klar Herr Commissar.  */
  418.  
  419.   df = calloc (1, sizeof (struct dvi_file));
  420.   if (df == NULL)
  421.     {
  422.       fatal ("Out of memory, sorry.\n");
  423.       return (1);
  424.     }
  425.  
  426.   df->f_name = malloc (1 + strlen (real_name));
  427.   if (df->f_name == NULL)
  428.     {
  429.       fatal ("Out of memory, sorry.\n");
  430.       return (1);
  431.     }
  432.  
  433.   strcpy (df->f_name, real_name);
  434.  
  435.   dviread_argv[0] = "6 * 9 == 42";
  436.   dviread_argv[1] = real_name;
  437.   page_ptr = &df->pages;
  438.   current_page_number = 0;
  439.   current_dvi_file = df;
  440.   loading_a_file = TRUE;
  441.   df->complete = FALSE;
  442.  
  443.   /* Switch on hourglass and start reading the dvi file. The accompanying
  444.      visdelay_end () is in DRAW_endpage, where the hourglass is switched off
  445.      after having loaded the first page.  */
  446.  
  447.   visdelay_begin ();
  448.   dviread_main (2, dviread_argv);
  449.  
  450.   df->complete = TRUE;
  451.   df->next = dvi_files;
  452.   dvi_files = df;
  453.  
  454.   /* Windows _must_ point to the newly loaded file's window.  */
  455.  
  456.   for (w = windows; w; w = w->next)
  457.     if (w->file == df)
  458.       set_window_title (w);
  459.  
  460.   loading_a_file = FALSE;
  461.   free (xname);
  462.   return (0);
  463. } /* read_a_file */
  464.  
  465.  
  466.  
  467.  
  468. /* Delete the display_window with window handle H from the list of window
  469.    display's.  If no such entry in the list can be found, just return
  470.    without further action.  */
  471.  
  472. void
  473. delete_display (wimp_w h)
  474. {
  475.   struct display **w, *t, *t2;
  476.   struct dvi_file *f, **pf;
  477.   int i;
  478.   struct page *p, *q;
  479.  
  480.   for (w = &windows; *w; w = &(*w)->next)
  481.     if ((*w)->w_handle == h)
  482.       break;
  483.  
  484.   if (*w)
  485.     {
  486.       t = *w;
  487.       *w = t->next;
  488.       for (t2 = windows; t2; t2 = t2->next)
  489.         if (t2->file == t->file)
  490.           break;
  491.  
  492.       /* If T2 is NULL, this is the last display onto that dvi file, so the
  493.          dvi file structure can be deleted as well.  */
  494.  
  495.       if (t2 == NULL)
  496.         for (pf = &dvi_files; *pf; pf = &(*pf)->next)
  497.           if (*pf == t->file)
  498.             {
  499.               f = *pf;
  500.               *pf = f->next;
  501.               for (i = 0; i < 256; i++)
  502.                 if (f->fonts[i])
  503.                   free (f->fonts[i]);
  504.               for (p = f->pages; p; p = q)
  505.                 {
  506. #ifdef USE_FLEX
  507.                   flex_free ((flex_ptr) &p->texts);
  508.                   flex_free ((flex_ptr) &p->rules);
  509.                   flex_free ((flex_ptr) &p->chars);
  510. #else
  511.                   free (p->texts);
  512.                   free (p->rules);
  513.                   free (p->chars);
  514. #endif
  515.                   q = p->next;
  516.                   free (p);
  517.                 }
  518.               break;
  519.             }
  520.  
  521. #ifdef USE_FLEX
  522.       flex_free ((flex_ptr) &t->area);
  523. #else
  524.       free (t->area);
  525. #endif
  526.       free (t);
  527.     }
  528. }
  529.  
  530. /******************************************
  531.  
  532.              DRAW_  routines
  533.  
  534.  ******************************************/
  535.  
  536.  
  537.  
  538. void
  539. DRAW_startpage(void)
  540. {
  541.   struct page *p = xcalloc (1, sizeof (struct page));
  542.  
  543.   p->dvi_page = ++current_page_number;
  544.   p->complete = FALSE;
  545.  
  546.   text_index = 0;
  547.   max_text_index = TEXT_BLOCKSIZE;
  548.  
  549. #ifdef USE_FLEX
  550.   if (flex_alloc ((flex_ptr) &p->texts, TEXT_BLOCKSIZE * sizeof (struct text)) == 0)
  551.     tfatal ("failed to allocate room for text");
  552. #else
  553.   p->texts = xmalloc (TEXT_BLOCKSIZE * sizeof (struct text));
  554. #endif
  555.  
  556.   rule_index = 0;
  557.   max_rule_index = RULE_BLOCKSIZE;
  558.  
  559. #ifdef USE_FLEX
  560.   if (flex_alloc ((flex_ptr) &p->rules, RULE_BLOCKSIZE * sizeof (struct rule)) == 0)
  561.     tfatal ("failed to allocate room for chars");
  562. #else
  563.   p->rules = xmalloc (RULE_BLOCKSIZE * sizeof (struct rule));
  564. #endif
  565.  
  566.   char_index = 0;
  567.   max_char_index = CHAR_BLOCKSIZE;
  568.  
  569. #ifdef USE_FLEX
  570.   if (flex_alloc ((flex_ptr) &p->chars, CHAR_BLOCKSIZE) == 0)
  571.     tfatal ("failed to allocated room for rules");
  572. #else
  573.   p->chars = xmalloc (CHAR_BLOCKSIZE);
  574. #endif
  575.  
  576.   *page_ptr = p;
  577.   page_ptr = &p->next;
  578.   p->things = 0;
  579.   current_page = p;
  580. }
  581.  
  582.  
  583.  
  584. void
  585. DRAW_text(int xl, int yb, int xr, int yt, char *text)
  586. {
  587.   struct text *t;
  588.   int i, len = 1 + strlen (text);
  589.  
  590.   yt = yt, xr = xr;   /* Indeed, to make cc shut up.  */
  591.  
  592.   /* If LEN == 1, a `zero string' was passed.  This could only come from
  593.      DRAW_char, so we got passed a one-character string with the character 0
  594.      in it.  */
  595.  
  596.   if (len == 1)
  597.     len = 2;
  598.  
  599.   if (char_index + len >= max_char_index)
  600.     {
  601.       max_char_index += CHAR_BLOCKSIZE;
  602. #ifdef USE_FLEX
  603.       if (flex_extend ((flex_ptr) ¤t_page->chars, max_char_index) == 0)
  604.         tfatal ("OUT OF MEMORY");
  605. #else
  606.       current_page->chars = xrealloc (current_page->chars, max_char_index);
  607. #endif
  608.     }
  609.  
  610.   for (i = 1; i < len; i++)
  611.     text[i - 1] |= 128;
  612.   strcpy (¤t_page->chars[char_index], text);
  613.  
  614.   if (text_index == max_text_index)
  615.     {
  616.       max_text_index += TEXT_BLOCKSIZE;
  617. #ifdef USE_FLEX
  618.       if (flex_extend ((flex_ptr) ¤t_page->texts, max_text_index * sizeof (struct text)) == 0)
  619.         tfatal ("OUT OF MEMORY");
  620. #else
  621.       current_page->texts = xrealloc (current_page->texts, max_text_index * sizeof (struct text));
  622. #endif
  623.     }
  624.  
  625.   t = ¤t_page->texts[text_index];
  626.   t->font = current_font_handle;
  627.   t->text = char_index;
  628.   t->x = xl;
  629.   t->y = yb;
  630.   t->rx = xr;
  631.   t->ty = yt;
  632.  
  633.   current_page->things++;
  634.   char_index += len;
  635.   text_index++;
  636.  
  637.   if (current_dvi_file->pages->complete && current_page->things % 66 == 0)
  638.     do_a_poll ();
  639. }
  640.  
  641.  
  642. /**********
  643.    Write one character.  This might be a special character (unprintable ASCII
  644.    code) hence this routine, which tweaks the character and just calls
  645.    DRAW_text to print it.  */
  646.  
  647. void
  648. DRAW_char(int xl, int yb, char c)
  649. {
  650.   char a[2];
  651.  
  652.   a[0] = c; a[1] = 0;
  653.   DRAW_text (xl, yb, xl + 100, yb, a);
  654.  
  655.   if (debug)
  656.     fprintf(stderr, "Draw_char(xl = %d, yb = %d, char = %d)\n", xl, yb, c);
  657. }
  658.  
  659.  
  660. /**********
  661.    Draw a rule at the specified position (X, Y) and of the specified width DX
  662.    and height DY.  */
  663.  
  664. void
  665. DRAW_rule(int x, int y, int dy, int dx)
  666. {
  667.   struct rule *r;
  668.  
  669.   if (rule_index == max_rule_index)
  670.     {
  671.       max_rule_index += RULE_BLOCKSIZE;
  672. #ifdef USE_FLEX
  673.       if (flex_extend ((flex_ptr) ¤t_page->rules, max_rule_index * sizeof (struct rule)) == 0)
  674.         tfatal ("barf r1");
  675. #else
  676.      current_page->rules = xrealloc (current_page->rules, max_rule_index * sizeof (struct rule));
  677. #endif
  678.     }
  679.  
  680.   r = ¤t_page->rules[rule_index];
  681.  
  682.   r->x = x;
  683.   r->y = y;
  684.   r->w = dx;
  685.   r->h = dy;
  686.  
  687.   current_page->things++;
  688.   rule_index++;
  689.  
  690. #if 0
  691. printf ("%d %d %d %p %p %p\n", char_index, text_index, rule_index, current_page->chars, current_page->texts, current_page->rules);
  692. #endif
  693.  
  694.   if (debug)
  695.     fprintf(stderr, "Draw_rule(xl = %d, yb = %d, dx = %d, dy = %d)\n", x, y, dx, dy);
  696. }
  697.  
  698.  
  699. /**********
  700.    Select a new current font.  */
  701.  
  702. void
  703. DRAW_selfont(int fno)
  704. {
  705.   current_font_handle = fno;
  706.   if (debug) fprintf(stderr, "Draw_selfont (fno = %d)\n", fno);
  707. }
  708.  
  709.  
  710. /**********
  711.    Define a font, named FNAME, of size SIZE, and to be identified as FNO.
  712.    SIZE is in 16th of a point.  Also check if the font actually exists, so an
  713.    error can be issued, because if the font appears not to be present while
  714.    redrawing the sprite we can't issue an error message.  */
  715.  
  716. void
  717. DRAW_deffont(int fno, char *fname, int size, int mag)
  718. {
  719.   char *s;
  720.   struct font_use *f;
  721.   int fh;
  722.  
  723.   s = xmalloc (1 + strlen (fname));
  724.   sprintf (s, "%s", fname);
  725.  
  726.   set_font_path ();
  727.   err = font_find (s, size * mag / 1000, size * mag / 1000, 0, 0, &fh);
  728.   if (err)
  729.     {
  730.       fatal ("Cannot find font `%s': %s\n", fname, err->errmess);
  731.       reset_font_path ();
  732.       do_a_poll ();
  733.     }
  734.   else
  735.     {
  736.       font_lose (fh);
  737.       reset_font_path ();
  738.     }
  739.  
  740.   f = xcalloc (1, sizeof (struct font_use));
  741.   f->name = s;
  742.   f->size = size * mag / 1000;
  743.   current_dvi_file->fonts[fno] = f;
  744.  
  745.   reset_font_path ();
  746.  
  747.   if (debug)
  748.     fprintf(stderr, "Draw_deffont(no = %d, name = \"%s\", size = %d/16)\n", fno, fname, size);
  749. }
  750.  
  751.  
  752. /********
  753.    Mark the end of a page.  MAXH and MAXV are the observed limits for this
  754.    page; COUNT points to an array of TeX page counters.  */
  755.  
  756. void
  757. DRAW_endpage(int maxh, int maxv, int *count)
  758. {
  759.   memcpy (current_page->tex_pages, count, 10 * sizeof (int));
  760.   current_page->complete = TRUE;
  761.   current_dvi_file->height = maxv;
  762.   current_dvi_file->width = maxh;
  763.  
  764. #ifdef USE_FLEX
  765.   if (flex_extend ((flex_ptr) ¤t_page->texts, text_index * sizeof (struct text)) == 0)
  766.     tfatal ("barf e1");
  767.   if (flex_extend ((flex_ptr) ¤t_page->chars, char_index) == 0)
  768.     tfatal ("barf e2");
  769.   if (flex_extend ((flex_ptr) ¤t_page->rules, rule_index * sizeof (struct rule)) == 0)
  770.     tfatal ("barf e1");
  771. #else
  772.   current_page->texts = xrealloc (current_page->texts, text_index * sizeof (struct text));
  773.   current_page->chars = xrealloc (current_page->chars, char_index);
  774.   current_page->rules = xrealloc (current_page->rules, rule_index * sizeof (struct rule));
  775. #endif
  776.  
  777.   current_page->text_max = text_index;
  778.   current_page->rule_max = rule_index;
  779.   current_page->char_max = char_index;
  780.  
  781.   if (debug)
  782.     fprintf(stderr, "Draw_endpage(%d, %d, %d)\n", maxh, maxv, count[0]);
  783.  
  784.   if (current_page_number == 1)
  785.     {
  786.       build_a_window (current_dvi_file, current_dvi_file->pages);
  787.       visdelay_end ();
  788.     }
  789. }
  790.  
  791. /* EOF */
  792.